package emulator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import keyboard.Keyboard;
import keyboard.Position;

public class ResultCostCalculatorKeysPressed extends ResultCostCalculator {
	public ResultCostCalculatorKeysPressed(String strategy, int dictSize) {
		super(strategy, dictSize);
		this.costType = "keysPressed";
	}
	
	@Override
	public float CalnCost(Keyboard keyboard, Result result) {
		String word = result.GetWord();
		float cost = 0f;
		
		char lastKey = '?';
		for (int i = 0; i < word.length(); i++) {
			Position centre = (lastKey == '?') ? keyboard.GetLetterPosition('g') : keyboard.GetGroupCentrePosition(keyboard.GetKeysGroupOfLetter(lastKey));
			keyboard.GroupingStaticKeyboard(result.GetExpression(i));
			HashMap<Character, Character> groupsKey = keyboard.GetGroupsKey();
			char centreLetter = Keyboard.layout[(int)centre.r][(int)centre.c];
			lastKey = groupsKey.get(centreLetter);
			char nextKey = groupsKey.get(word.charAt(i));
			
			HashSet<Character> usedKey = new HashSet<Character>();
			ArrayList<Character> queue = new ArrayList<Character>();
			ArrayList<Integer> step = new ArrayList<Integer>();
			
			queue.add(lastKey);
			usedKey.add(lastKey);
			step.add(0);
			for (int j = 0; j < queue.size(); j++) {
				char key = queue.get(j);
				if (key == nextKey) {
					cost += step.get(j);
					break;
				}
				for (int dir = 0; dir < 4; dir++) {
					char nearbyKey = keyboard.GetNearbyKey(key, dir);
					if (!usedKey.contains(nearbyKey)) {
						queue.add(nearbyKey);
						usedKey.add(nearbyKey);
						step.add(step.get(j) + 1);
					}
				}
			}
			
			lastKey = nextKey;
		}
		
		cost += result.GetPriority();
		return cost;
	}
}
